import axios from 'axios'
import Vue from 'vue'
import {
  restUrl as baseUrl
} from '@/config'
import {
  codeHeaders,
  encryptBody
} from '@/tool/sm.js'
import notification from 'ant-design-vue/es/notification'
import store from '../store'
import { BUSINESS_MENU_TYPE } from '@/config/businessConfig'
import { getUrlParam } from '@/utils/util'


// 三个业务菜单下的接口需要额外传的参数
const businessAdditionalQuery = (type) => {
  const activeCodes = store.state.user.activeCodes
  const businessSearchConditions = store.state.user.businessSearchConditions
  let queryType
  Object.keys(BUSINESS_MENU_TYPE).forEach(key => {
    if(activeCodes.some(item => item === BUSINESS_MENU_TYPE[key].code)){
      queryType = key
    }
  })
  // 审批页面默认 queryType = 1
  if(getUrlParam('taskDefKey') || getUrlParam('procInstId') || getUrlParam('type') === 'approve'){
    queryType = 1
  }
  if(!queryType) return undefined
  if(queryType == 3){
    return {
      queryType,
      detSet: type === 'get' ? businessSearchConditions.detSet.join(',') : businessSearchConditions.detSet,
      orgSet: type === 'get' ? businessSearchConditions.orgSet.join(',') : businessSearchConditions.orgSet,
    }
  }else{
    return {
      queryType
    }
  }
}

axios.defaults.withCredentials = true

axios.defaults.baseURL = baseUrl
const accessError = e => {
  const data = (e && e.response && e.response.data) || {}
  //无效令牌
  if (parseInt(data.status) === 401) {
    store.dispatch('SetHasRouters', false)
    // 退出登录
    Vue.getAcloudProvider().logout()
  } else if (parseInt(data.status) === 500 && data.code.search('ycloud-user') != -1) {
    return data
  } else {
    if (e?.response?.config?.unNotify) return e?.response?.data || {}
    notification.error({
      message: '提示',
      description: data.error_description || data.message || '请求失败，请稍后重试！'
    })
  }
}
// request拦截器
axios.interceptors.request.use((config) => {

  //只针对删除接口：ids:[null]后端报错的情况。做一个统一处理把null去掉
  //触发条件：1、post或者put。2、data不为空并且不为string。3、data里面有ids这个字段并且类型为数组
  if (config.method === 'post' || config.method === 'put') {
    if (config.data) {
      let data = null
      if (typeof config.data === 'string') {
        try {
          data = JSON.parse(config.data)
        } catch (e) {
          //不是目标
        }
      } else {
        data = config.data
      }
      if (data && data['ids']) {
        let value = data['ids']
        if (typeof value === 'object') {
          let newValue = []
          value.map(v => {
            if (v !== 0 && v !== null && v !== undefined) {
              newValue.push(v)
            }
          })
          data['ids'] = newValue
          config.data = data
        }
      }
    }
    // 三个业务菜单下的接口需要额外添加数据筛选的字段
    const additionalQuery = businessAdditionalQuery()
    if(additionalQuery && !(config.data instanceof FormData)){
      if(config.data?.param && !Array.isArray(config.data?.param)){
        config.data.param = {
          ...config.data.param,
          ...additionalQuery,
        }
      }else if(config.data?.query && !Array.isArray(config.data.query)){
        config.data.query = {
          ...config.data.query,
          ...additionalQuery,
        }
      }else if(!Array.isArray(config.data)){
        config.data = {
          ...config.data,
          ...additionalQuery,
        }
      }
    }
  }

  // 如果没有设置Content-Type，默认application/json
  if (!config.headers['Content-Type']) {
    config.headers['Content-Type'] = 'application/json'
  }
  // 方法做防重返和防篡改
  // if (process.env.VUE_APP_ENCRYPTION === '1') {
  config = codeHeaders(config)
  config = encryptBody(config)
  // }
  // 每次发送请求之前判断vuex中是否存在token
  // 如果存在，则统一在http请求的header都加上token
  const token = Vue.getAcloudProvider().getAccessToken()
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
  }
  return config
}, error => {
  return Promise.reject(error)
})

axios.interceptors.response.use(
  response => {
    const resCode = response.data.code
    const whiteArr = ['orgs/saveBaseOrg','orgs/desensitize/id','orgs/updateBaseOrg','/posts/save-from-template/three','/posts/update/basic/three']
    if (whiteArr.some((it) => response.config.url.includes(it))) {
      return response
    }else if (resCode && typeof resCode == 'number' && resCode !== 200 || resCode && !isNaN(Number(resCode)) && typeof resCode === 'string' && resCode !== '0' && resCode !== '1' && resCode !== '-1') {
      !response.config.unNotify && notification.error({
        message: '提示',
        description: response.data.message || response.data.msg || '请求失败，请稍后重试！'
      })
      // console.log(response)
      // if (!response.data.data)response.data.data = {}
      if (response.config.unReject) {
        return response
      }
      return Promise.reject(response)
    }
    if (response.data.data || response.data.data == 0) {
      return response.data
    }
    return response
  }, error => {
    console.log(error)
    // accessError(error)
    // console.log('error', error)
    // 非法的身份或者身份过期，需要重新登录
    // if (error.response.status === 401) {
    //   router.push('/err401')
    //   return
    // }
    // // 未授权访问，给用户提示或路由到一个其他错误页面
    // if (error.response.status === 403) {
    //   console.error(error)
    //   router.push('/err403')
    //   return
    // }
    return Promise.reject(accessError(error))
  })

export default axios

export function get(url, params = {}) {
  return new Promise((resolve, reject) => {
    axios
      .get(url, {
        params: params
      })
      .then(response => {
        resolve(response)
      })
      .catch(err => {
        reject(err)
      })
  })
}

/**
 * post request
 * @param url
 * @param data
 * @param time 超时时间
 * @returns {Promise}
 */
export function post(url, data = {}, time) {
  return new Promise((resolve, reject) => {
    axios.post(url, data, time).then(
      response => {
        resolve(response)
      },
      err => {
        reject(err)
      }
    )
  })
}

/**
 * put request
 * @param url
 * @param data
 * @returns {Promise}
 */
export function put(url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.put(url, data).then(
      response => {
        resolve(response)
      },
      err => {
        reject(err)
      }
    )
  })
}

/**
 * delete request
 * @param url
 * @param data
 * @returns {Promise}
 */
export function remove(url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.delete(url, data).then(
      response => {
        resolve(response)
      },
      err => {
        reject(err)
      }
    )
  })
}
